#include <string.h>
#include <stdlib.h>
#include <stdarg.h>
#include "qi_type.h"
#include "../q_common.h"



/* hash table with all defined types */
struct qi_typetable qi_types;

static struct qi_type* qi_chaintypelookup(const char* const name, struct qi_type* chain)
{
	for(; chain; chain = chain->next)
		if(!strncmp(chain->name, name, Q_MAX_SYMBOL_LENGTH))
			return chain;
	return NULL;
}

struct qi_type* qi_typelookup(const char* const name)
{
	int i;
	if(!name)
		return NULL;
	for(i = 0; i < Q_HASH_TABLE_SIZE; ++i)
	{
		struct qi_type* tmp = qi_chaintypelookup(name, qi_types.data[i]);
		if(tmp)
			return tmp; 
	}
	return NULL;
}

static void qi_simpleaddtype(struct qi_type* type)
{
	struct qi_type* tmp = qi_types.data[q_hashname(type->name)];
	if(!tmp)
		qi_types.data[q_hashname(type->name)] = type;
	else
	{
		for(; tmp->next; tmp = tmp->next);
		tmp->next = type;
	}
}

int qi_addtype(const char* const name, int size, ...)
{
	struct qi_type* type;

	if(!name || qi_typelookup(name))
		return -1;

	if(!(type = (struct qi_type*)malloc(sizeof(struct qi_type))))
			return -1;
	strncpy(type->name, name, Q_MAX_SYMBOL_LENGTH);
	type->next = NULL;

	if(size > 0)
	{
		va_list vl;
		int i;
		const char* tmp;
		type->size = size;
		if(!(type->members = (struct qi_structmember*)malloc(size * sizeof(struct qi_structmember))))
		{
			free(type);
			return -1;
		}
		va_start(vl, size);
		for(i = 0; i < size; ++i)
		{
			tmp = va_arg(vl, const char*);
			if(!qi_typelookup(tmp))
			{
				free(type->members);
				free(type);
				return -1;
			}
			else
			{
				strncpy(type->members[i].name, tmp, Q_MAX_SYMBOL_LENGTH);
			}
		}
		va_end(vl);
	}	
	else
		type->size = 0;
	qi_simpleaddtype(type);
	return 0;
}







